package com.example.huajia.wx.service.impl;

import cn.hutool.core.date.DateTime;
import com.example.huajia.wx.db.dao.TbActivityDao;
import com.example.huajia.wx.service.ActivityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import static com.example.huajia.wx.common.util.RedisKey.*;


@Service
@Slf4j
public class ActivityServiceImpl implements ActivityService {

    @Resource
    private TbActivityDao activityDao;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 分页查询最新更新的活动
     *
     * @return list
     */
    @Override
    public ArrayList<HashMap> searchAllActivityByPage(HashMap param) {
        ArrayList<HashMap> list = activityDao.searchAllActivityByPage(param);
        String key = ACTIVITY_ALL_KEY;
        //查询完之后需要把数据写到redis里面去
        redisTemplate.delete(key);
        for (HashMap map : list) {
            redisTemplate.opsForList().rightPush(key, map);
        }
        redisTemplate.expire(key, 30L, TimeUnit.MINUTES);
        //返回数据
        return list;
    }

    @Override
    public ArrayList<HashMap> searchMyPublishByPage(HashMap param) {
        Integer userId = (Integer) param.get("publisherId");
        ArrayList<HashMap> list = activityDao.searchMyPublishByPage(param);
        String key = ACTIVITY_MY_ACTIVITY_KEY + userId;
        //查询完之后需要把数据写到redis里面去
        for (HashMap map : list) {
            redisTemplate.opsForList().rightPush(key, map);
        }
        redisTemplate.expire(key, 5L, TimeUnit.MINUTES);
        //返回数据
        return list;
    }

    @Override
    public ArrayList<HashMap> searchMyParticipationByPage(HashMap param) {
        Integer userId = (Integer) param.get("userId");
        ArrayList<HashMap> list = activityDao.searchMyParticipationByPage(param);
        String key = ACTIVITY_MY_PAR_KEY + userId;
        //查询完之后需要把数据写到redis里面去
        for (HashMap map : list) {
            redisTemplate.opsForList().rightPush(key, map);
        }
        redisTemplate.expire(key, 5L, TimeUnit.MINUTES);
        //返回数据
        return list;
    }

    @Override
    public ArrayList<HashMap> searchActivityContentById(String id) {
        String key = ACTIVITY_CONTENT_KEY + id;
        //当redis的数据为空时会进入这里
        ArrayList<HashMap> list = activityDao.searchActivityContentById(id);
        //将数据添加到redis里面去
        redisTemplate.opsForList().leftPush(key, list);
        redisTemplate.expire(key, 30L, TimeUnit.MINUTES);
        return list;
    }

    @Override
    public Integer insertActivity(HashMap param) {
        String key = ACTIVITY_ALL_KEY;
        //先将新增的数据更新到数据库
        Integer row = activityDao.insertActivity(param);
        if (row == null) {
            return null;
        }
        String district = (String) param.get("district");
        String id = (String) param.get("id");
        String place = (String) param.get("place");
        String title = (String) param.get("title");
        Integer lea = (Integer) param.get("lea");
        Integer userId = (Integer) param.get("publisherId");
        HashMap map = new HashMap();
        map.put("createTime", DateTime.now().toString());
        map.put("district", district);
        map.put("id", id);
        map.put("place", place);
        map.put("title", title);
        map.put("lea", lea);
        ArrayList<HashMap> list = new ArrayList<>();
        list.add(map);
        //接着将新增的数据更新到redis中去
        redisTemplate.opsForList().leftPush(key, list.get(0));
        redisTemplate.expire(key, 30L, TimeUnit.MINUTES);
        //让存在我的发布里面的redis中的key失效
        String myActivityKey = ACTIVITY_MY_ACTIVITY_KEY + userId;
        redisTemplate.expire(myActivityKey, 1L, TimeUnit.SECONDS);
        return row;
    }

    @Override
    public Integer updateActivityEnrollment(HashMap param) {
        String id = (String) param.get("id");
        Integer userId = (Integer) param.get("userId");
        //首先判断该用户是否已经报名
        String enrollmentUser = activityDao.searchEnrollmentUserById(id);
        if (enrollmentUser != null) {
            ArrayList list = new ArrayList();
            //这里的操作是为了把已报名的用户的id拿到
            enrollmentUser = enrollmentUser.substring(1, enrollmentUser.length() - 1);
            String[] strArray = enrollmentUser.split(",");
            //接着把已报名的用户跟现在来报名的用户的id进行对比，看是否是重复报名
            for (String s : strArray) {
                if (userId.toString().equals(s.trim())) {
                    return -1;
                }
                list.add(s);
            }
            list.add(userId.toString());
            param.replace("enrollmentUser", list.toString());
        }

        //接着到数据库更新剩余名额
        Integer row = activityDao.updateActivityEnrollment(param);
        //判断是否更新成功
        if (row == null) {
            return null;
        }
        String key = ACTIVITY_ALL_KEY;
        String myActivityKey = ACTIVITY_MY_ACTIVITY_KEY + userId;
        String myParActivityKey = ACTIVITY_MY_PAR_KEY + userId;
        redisTemplate.expire(myActivityKey, 1L, TimeUnit.SECONDS);
        redisTemplate.expire(myParActivityKey, 1L, TimeUnit.SECONDS);
        //设置redis立即过期，目的是更新redis数据
        redisTemplate.expire(key, 1L, TimeUnit.SECONDS);
        return row;
    }

    @Override
    public ArrayList<HashMap> searchActivityByKeyByPage(HashMap param) {
        ArrayList<HashMap> list = activityDao.searchActivityByKeyByPage(param);
        return list;
    }

    @Override
    public int checkIn(HashMap param) {
        String id = (String) param.get("id");
        Integer userId = (Integer) param.get("userId");
        //首先判断该用户是否已经签到
        String checkedIn = activityDao.searchCheckInUserById(id);
        if (checkedIn != null) {
            ArrayList list = new ArrayList();
            //这里的操作是为了把已报名的用户的id拿到
            checkedIn = checkedIn.substring(1, checkedIn.length() - 1);
            String[] strArray = checkedIn.split(",");
            //接着把已报名的用户跟现在来报名的用户的id进行对比，看是否是重复报名
            for (String s : strArray) {
                if (userId.toString().equals(s.trim())) {
                    return -1;
                }
                list.add(s);
            }
            list.add(userId.toString());
            param.replace("checkedIn", list.toString());
        }
        int row = activityDao.checkIn(param);
        return row;
    }
}
